package com.hf.providerexport.database;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.util.Log;

public class DatabaseHelper {
    private static final String TAG = DatabaseHelper.class.getName();
    private SQLiteDatabase mDatabase;
    private String mFilePath = null;

    public DatabaseHelper(String path, boolean deleteOld) {
        newDatabase(path, deleteOld);
    }

    private synchronized void newDatabase(String path, boolean deleteOld) {
        // close previous db
        if (mDatabase != null && mDatabase.isOpen()) {
            mDatabase.close();
        }

        // delete db file if exists
        mFilePath = path;
        File file = new File(mFilePath);
        if (deleteOld) {
            if (file.exists()) {
                if (file.delete()) {
                    Log.i(TAG, "db file deleted: " + mFilePath);
                } else {
                    Log.w(TAG, "db file delete failed: " + mFilePath);
                }
            }

            String tempPath = mFilePath + "-journal";
            File tempFile = new File(tempPath);
            if (tempFile.exists()) {
                if (tempFile.delete()) {
                    Log.i(TAG, "db file deleted: " + tempPath);
                } else {
                    Log.w(TAG, "db file delete failed: " + tempPath);
                }
            }
        }

        // create dirs if necessary
        File dirFile = new File(file.getParent());
        if (!dirFile.exists()) {
            if (!dirFile.mkdirs()) {
                Log.w(TAG, "Failed to create db parent directory.");
            }
        }

        // create database
        mDatabase = SQLiteDatabase.openOrCreateDatabase(path, null);

        // init
        initDatabase();
    }

    public String getFilePath() {
        return mFilePath;
    }

    private synchronized void initDatabase() {
        // empty implement
    }

    public void dropTable(String table) {
        mDatabase.execSQL("DROP TABLE " + table);
    }

    public void createTable(String table, String[] columns, int[] types) {
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE ").append(table).append(" (");
        for (int i=0; i<columns.length; i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append("[").append(columns[i]).append("] ").append(getTypeName(types[i]));
        }
        sb.append(")");

        String sql = sb.toString();

        mDatabase.execSQL(sql);
    }

    private String getTypeName(int type) {
        switch (type) {
            case Cursor.FIELD_TYPE_BLOB:
                return "BOLB";
            case Cursor.FIELD_TYPE_FLOAT:
                return "REAL";
            case Cursor.FIELD_TYPE_INTEGER:
                return "INTEGER";
            case Cursor.FIELD_TYPE_NULL:
            case Cursor.FIELD_TYPE_STRING:
            default:
                return "TEXT";
        }
    }

    public void execute(String sql) {
        mDatabase.execSQL(sql);
    }

    public Cursor query(String table, String[] columns, String selection, String[] selectionArgs) {
        return query(table, columns, selection, selectionArgs, null, null, null);
    }

    public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        return mDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
    }

    public long inserts(String table, List<ContentValues> valuesList) {
        return inserts(table, null, valuesList);
    }

    public long inserts(String table, String nullColumnHack, List<ContentValues> valuesList) {
        long ret = -1;
        mDatabase.beginTransaction();

        try {
            for (ContentValues values : valuesList) {
                ret = mDatabase.insert(table, nullColumnHack, values);
            }
            mDatabase.setTransactionSuccessful();
            return ret;
        } finally {
            mDatabase.endTransaction();//这个操作是在磁盘进行的所以比较耗时。
        }
    }

    public long insert(String table, ContentValues values) {
        return insert(table, null, values);
    }

    public long insert(String table, String nullColumnHack, ContentValues values) {
        long ret = -1;
        mDatabase.beginTransaction();

        try {
            ret = mDatabase.insert(table, nullColumnHack, values);
            mDatabase.setTransactionSuccessful();
            return ret;
        } finally {
            mDatabase.endTransaction();//这个操作是在磁盘进行的所以比较耗时。
        }
    }

    public long insertNoTran(String table, ContentValues values) {
        return insertNoTran(table, null, values);
    }

    public long insertNoTran(String table, String nullColumnHack, ContentValues values) {
        return mDatabase.insert(table, nullColumnHack, values);
    }

    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
        int ret = -1;
        mDatabase.beginTransaction();

        try {
            ret = mDatabase.update(table, values, whereClause, whereArgs);
            mDatabase.setTransactionSuccessful();
            return ret;
        } finally {
            mDatabase.endTransaction();
        }
    }

    public int delete(String table, String whereClause, String[] whereArgs) {
        int ret = -1;
        mDatabase.beginTransaction();
        try {
            ret = mDatabase.delete(table, whereClause, whereArgs);
            mDatabase.setTransactionSuccessful();
            return ret;
        } finally {
            mDatabase.endTransaction();
        }
    }

    public void beginTransaction() {
        mDatabase.beginTransaction();
    }

    public void setTransactionSuccessful() {
        mDatabase.setTransactionSuccessful();
    }

    public void endTransaction() {
        mDatabase.endTransaction();
    }

    public void close() {
        mDatabase.close();
    }

}
